<!DOCTYPE html>
<html>

	<head>
		<meta charset="UTF-8">
		<title>原型</title>
	</head>

	<body>
	</body>
	<script>
		//原型
		function Box() {} //构造函数函数体内什么都没有，如果有叫做实例属性，实例方法

		Box.prototype.name = 'lee'; //原型属性
		Box.prototype.age = 100; //原型属性
		Box.prototype.run = function() { //原型方法
			return this.name + this.age + '运行中...';
		};
		
		
		//调用
		var box1 = new Box();
		alert(box1.run());
		
		//如果是实例方法，不同的实例化，他们的方法地址是不一样的
		//如果是原型方法，那么他们的地址是共享的，大家都一样
		
		var box2 = new Box();
		alert(box1.run()==box2.run());//true
		
		alert(box1.prototype);//undefined 这个属性是一个对象，访问不到
		alert(box1.__proto__);//[object Object]这个属性是一个指针指向prototype
	
	//constructor构造属性，可以获取构造函数本身，作用是被原型指针定位，
	//然后得到构造函数本身其实就是对象实例对应的原型对象的作用
	alert(box1.constructor);//function Box() {}
	
	//判断一个对象实例（对象引用）是不是指向了原型对象，基本上只要实例化了他就自动指向的
	alert(Box.prototype.isPrototypeOf(box1));//true
	
	//就近原则
	box2.name ='Tmo';//box2的实例属性
	alert(box2.name);//Tom
	alert(box1.name);//lee  实例属性无法共享
	
	delete box2.name;//可以删除实例中的属性
	alert(box2.name);//lee
	
	//删除原型的属性
	delete Box.prototype.name;
	alert(box2.name);//undefined
	//覆盖原型中的属性
	Box.prototype.name='lionkk';
	alert(box2.name);//lionkk
	
	//判读属性是在构造函数里的实例还是在原型中 
	alert(box1.hasOwnProperty('age'));//false  >>实例里有返回true,否则返回false
	//in 操作符会在通过对象能够访问给定属性时返回true，无论改属性存在于实例中还是原型中
	alert('name' in box1);//true  存在实例或原型中
	
	//原型模式的执行流程
	//1先查找构造函数实例里的属性和方法，如果有，立刻返回；
	//2如果构造函数实例里没有，则去它的原型对象里找，如果有，就返回。
	//虽然我们可以通过对象实例访问保存在原型中的值，
	//但却不能访问通过对象实例重写原型中的值。
	
	</script>

</html>